/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

/**
 * 财务管理APP充值金额查询
 *  */

import React, { useState, useEffect } from 'react';
import { PageContainer } from '@ant-design/pro-layout';
import {
  AutoComplete,
  Tabs,
  Form,
  Select,
  Card,
  notification,
  Row,
  Col,
  Button,
  message,
} from 'antd';
import { DeleteTwoTone, EditTwoTone } from '@ant-design/icons';
import EditableTable from '@/components/Table/EditableTable';
import ReactJson from 'react-json-view';
import { getQueryStatus } from '@/services/postman';
import styles from './index.less';

const { Option } = Select;
const FormItem = Form.Item;
const { TabPane } = Tabs;

const STATUS = {
  200: { color: '#67C23A', text: 'OK' },
  401: { color: '#F56C6C', text: 'unauthorized' },
  400: { color: '#F56C6C', text: 'Bad Request' },
};
const tabExtra = (response: any) => {
  return response && response.data ? (
    <div style={{ marginRight: 16 }}>
      <span>
        Status:
        <span
          style={{
            color: STATUS[response.status_code] ? STATUS[response.status_code].color : '#F56C6C',
            marginLeft: 8,
            marginRight: 8,
          }}
        >
          {response.status_code}{' '}
          {STATUS[response.status_code] ? STATUS[response.status_code].text : ''}
        </span>
        <span style={{ marginLeft: 8, marginRight: 8 }}>
          Time: <span style={{ color: '#67C23A' }}>{response.cost}</span>
        </span>
        <span style={{ marginLeft: 8, marginRight: 8 }}>
          Size: <span style={{ color: '#67C23A' }}>{response.size}</span>
        </span>
      </span>
    </div>
  ) : null;
};

const PostmanForm: React.FC<any> = ({ bordered = null, request_method = 'get' }) => {
  const [form] = Form.useForm();
  const defaultBody = [{ id: 1, key: '', value: '' }];
  const defaultParam = [{ id: 2, key: '', value: '' }];
  const defaultHeader = [{ id: 3, key: '', value: '' }];
  const [method, setMethod] = useState('get');
  const [bodyData, setBodyData] = useState(defaultBody);
  const [bodysKeys, setBodysKeys] = useState(() => bodyData.map((item: any) => item.id));
  const [paramsData, setParamsData] = useState(defaultParam);
  const [editableKeys, setEditableRowKeys] = useState(() => paramsData.map((item: any) => item.id));
  const [headers, setHeaders] = useState([
    { id: 3, key: 'Content-Type', value: 'application/x-www-form-urlencoded' },
    { id: 4, key: '', value: '' },
  ]);
  const [headersKeys, setHeadersKeys] = useState(() => headers.map((item: any) => item.id));
  const [loading, setLoading] = useState(false);
  const [url, setUrl] = useState('');
  const [response, setResponse] = useState({});

  useEffect(() => {
    setMethod(request_method);
  }, [request_method]);

  const splitUrl = (nowUrl: any) => {
    const split = nowUrl.split('?');
    if (split.length < 2) {
      setParamsData(defaultParam);
    } else {
      const params = split[1].split('&');
      const newParams: any = [];
      const keys: any = [];
      params.forEach((item: any, idx: any) => {
        const [key, value] = item.split('=');
        const now = Date.now();
        keys.push(now + idx + 10);
        newParams.push({ key, value, id: now + idx + 10 });
      });
      if (params[params.length - 1].split('=')[0]) {
        keys.push(Date.now());
        newParams.push({ key: '', value: '', id: Date.now() });
      }
      setParamsData(newParams);
      setEditableRowKeys(keys);
    }
  };
  // 根据paramsData拼接url
  const joinUrl = (data: any) => {
    const send_url = form.getFieldValue('url');
    let tempUrl: string = '';
    if (send_url === undefined) {
      tempUrl = '';
    } else {
      tempUrl = `${send_url}`.split('?')[0];
    }
    data.forEach((item: any, idx: number) => {
      if (item.key) {
        // 如果item.key有效
        if (idx === 0) {
          tempUrl = `${tempUrl}?${item.key}=${item.value || ''}`;
        } else {
          tempUrl = `${tempUrl}&${item.key}=${item.value || ''}`;
        }
      }
    });
    // setUrl(tempUrl);
    form.setFieldsValue({ url: tempUrl });
  };

  const onDelete = (columnType: any, key: any) => {
    if (columnType === 'params') {
      let data = paramsData.filter((item: any) => item.id !== key);
      if (!paramsData.length) {
        data = defaultParam;
      }
      setParamsData(data);
      joinUrl(data);
    } else if (columnType === 'body') {
      let data = bodyData.filter((item: any) => item.id !== key);
      if (!bodyData.length) {
        data = defaultBody;
      }
      setBodyData(data);
    } else {
      let data = headers.filter((item: any) => item.id !== key);
      if (!headers.length) {
        data = defaultHeader;
      }
      setHeaders(data);
    }
  };

  const columns = (columnType: string) => {
    return [
      {
        title: 'KEY',
        key: 'key',
        dataIndex: 'key',
      },
      {
        title: 'VALUE',
        key: 'value',
        dataIndex: 'value',
      },
      {
        title: '操作',
        valueType: 'option',
        render: (text: string, record: any) => {
          return (
            <>
              <EditTwoTone
                style={{ cursor: 'pointer' }}
                onClick={() => {
                  setEditableRowKeys([record.id]);
                }}
              />
              <DeleteTwoTone
                style={{ cursor: 'pointer', marginLeft: 8 }}
                onClick={() => {
                  onDelete(columnType, record.id);
                }}
                twoToneColor='#eb2f96'
              />
            </>
          );
        },
      },
    ];
  };

  const hideOptionColumns = () => {
    return [
      {
        title: 'KEY',
        key: 'key',
        dataIndex: 'key',
      },
      {
        title: 'VALUE',
        key: 'value',
        dataIndex: 'value',
      },
    ];
  };
  // 处理headers
  const getRequestData = (requestType: string) => {
    const data = {
      headers: headers,
      body: bodyData,
    };
    const result = {};
    data[requestType].forEach((item: any) => {
      if (item.key !== '') {
        result[item.key] = item.value;
      }
    });
    return result;
  };

  const verifyEmpty = (params: any) => {
    if (!params) return;
    const arr = params.filter((item) => {
      return item.key || item.value;
    });
    return arr;
  };

  // 拼接http请求
  const onRequest = async () => {
    const send_url = form.getFieldValue('url');
    if (!send_url) {
      notification.error({
        message: '请求Url不能为空',
      });
      return;
    }
    setLoading(true);
    const params = {
      method: method || 'get',
      url: send_url,
      requestBody: JSON.stringify({
        paramsData: verifyEmpty(paramsData),
        bodyData: verifyEmpty(bodyData),
      }),
      requestHeader: JSON.stringify(getRequestData('headers')),
    };
    const res = await getQueryStatus(params);
    setLoading(false);
    const { code, msg } = res;
    setResponse(res.data);
    if (code == 0) {
      message.success(msg);
    } else {
      message.error(msg);
    }
  };

  return (
    <PageContainer className={styles.main} title='http请求监控'>
      <Card bordered={bordered}>
        <Form form={form}>
          <Row gutter={[8, 8]}>
            <Col span={18} className={styles.search_box}>
              <FormItem
                name='request_method'
                rules={[{ required: true, message: '请选择请求方法' }]}
                initialValue={method}
              >
                <Select
                  placeholder='选择请求方式'
                  onChange={(data: string) => setMethod(data)}
                  style={{ width: 120, textAlign: 'left' }}
                  size='large'
                >
                  <Option key='get' value='get'>
                    GET
                  </Option>
                  <Option key='post' value='post'>
                    POST
                  </Option>
                </Select>
              </FormItem>
              <FormItem name='url' rules={[{ required: true, message: '请输入要请求的url' }]}>
                <AutoComplete
                  placeholder='请输入要请求的url'
                  size='large'
                  onChange={(string: any, e: any) => {
                    if (e.key && url && url.indexOf(string) === -1) {
                      const value = `${url}${string}`;
                      splitUrl(value);
                      form.setFieldsValue({ url: value });
                      setUrl(value);
                    } else {
                      splitUrl(string);
                      form.setFieldsValue({ url: string });
                      setUrl(string);
                    }
                  }}
                />
              </FormItem>
              <div style={{ float: 'right' }}>
                <Button onClick={onRequest} loading={loading} type='primary' size='large'>
                  Send
                </Button>
              </div>
            </Col>
          </Row>
          <Row style={{ marginTop: 8 }}>
            <Tabs defaultActiveKey='1' style={{ width: '100%' }}>
              <TabPane tab='Params' key='1'>
                <EditableTable
                  columns={paramsData.length > 1 ? columns('params') : hideOptionColumns()}
                  title='Query Params'
                  dataSource={paramsData}
                  setDataSource={setParamsData}
                  extra={joinUrl}
                  editableKeys={editableKeys}
                  setEditableRowKeys={setEditableRowKeys}
                />
              </TabPane>
              <TabPane tab='Headers' key='2'>
                <EditableTable
                  columns={headers.length > 1 ? columns('headers') : hideOptionColumns()}
                  title='Headers'
                  dataSource={headers}
                  setDataSource={setHeaders}
                  editableKeys={headersKeys}
                  setEditableRowKeys={setHeadersKeys}
                />
              </TabPane>
              <TabPane tab='Body' key='3'>
                <EditableTable
                  columns={bodyData.length > 1 ? columns('body') : hideOptionColumns()}
                  title='Body'
                  dataSource={bodyData}
                  setDataSource={setBodyData}
                  editableKeys={bodysKeys}
                  setEditableRowKeys={setBodysKeys}
                />
              </TabPane>
            </Tabs>
          </Row>
          <Row gutter={[8, 8]}>
            {Object.keys(response).length === 0 ? null : (
              <Tabs style={{ width: '100%' }} tabBarExtraContent={tabExtra(response)}>
                <TabPane tab='Body' key='1'>
                  <ReactJson
                    src={response.data}
                    name={false}
                    theme='lighter'
                    enableClipboard={true}
                    displayObjectSize={false}
                    displayDataTypes={true}
                  />
                </TabPane>
              </Tabs>
            )}
          </Row>
        </Form>
      </Card>
    </PageContainer>
  );
};

export default PostmanForm;
